using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Volume2D
{
    enum Type { Ellipse = 1, Cone, Rectangle };

    public int leafNumber = 1500;
    public Vector3 centerPosition = Vector3.zero;
    // Ellipsoid
    public Vector2 ellipseRadius = new Vector2(5f, 5f);
    public float ellipseDensity = 1f;
    public Vector2 ellipseOffsetX = new Vector2(-1f, 1f);
    public Vector2 ellipseOffsetY = new Vector2(-1f, 1f);
    // Cone
    public float coneRadius = 5f;
    public float coneHeight = 5f;
    public float coneDensity = 1f;
    public Vector2 coneOffsetX = new Vector2(-1f, 1f);
    public Vector2 coneOffsetY = new Vector2(-1f, 1f);
    public Vector2 coneOffsetZ = new Vector2(-1f, 1f);
    // Rectangle
    public float rectangleX = 5f;
    public float rectangleY = 5f;
    public float rectangleDensity = 1f;

    public Volume2D()
    {
    }

    public Volume2D(Vector3 position)
    {
        centerPosition = position;
    }

    public void GenerateLeaves(ref List<Leaf2D> leaves, int volumeType)
    {
        switch (volumeType)
        { 
            case 0:
                GenerateLeavesEllipse(ref leaves);
                break;
        }
    }

    public void GenerateLeavesEllipse(ref List<Leaf2D> leaves)
    {
        for (int i = 0; i < leafNumber; i++)
        {
            float r = ellipseRadius.x;
            if (ellipseRadius.y > ellipseRadius.x)
                r = ellipseRadius.y;

            Vector2 p;
            do
            {
                p = Random.insideUnitCircle * r;
            }
            while (
                  p.x < ellipseOffsetX.x * ellipseRadius.x ||
                  p.x > ellipseOffsetX.y * ellipseRadius.x ||
                  p.y < ellipseOffsetX.x * ellipseRadius.y ||
                  p.y > ellipseOffsetX.y * ellipseRadius.y ||
                  (Mathf.Pow(p.x, 2) / Mathf.Pow(ellipseRadius.x, 2)) + (Mathf.Pow(p.y, 2) / Mathf.Pow(ellipseRadius.y, 2)) > 1.0f ||
                  (Mathf.Pow(p.x, 2) / Mathf.Pow(ellipseRadius.x, 2)) + (Mathf.Pow(p.y, 2) / Mathf.Pow(ellipseRadius.y, 2)) <= (1.0f - ellipseDensity));
            leaves.Add(new Leaf2D(centerPosition + new Vector3(p.x, p.y, 0f)));
        }
    }

    public void GenerateLeavesCone(ref List<Leaf2D> leaves)
    {
        for (int i = 0; i < leafNumber; i++)
        {
            float r = coneRadius;
            if (coneHeight > coneRadius * 2)
                r = coneHeight;
            Vector3 p;
            do
            {
                p = Random.insideUnitSphere * r;
            }
            while (
                  (Mathf.Pow(p.x, 2) + Mathf.Pow(p.y, 2)) / (coneRadius / coneHeight) > Mathf.Pow(p.z - coneHeight, 2));
            leaves.Add(new Leaf2D(centerPosition + p));
        }
    }

    public void GenerateLeavesRectangle(ref List<Leaf2D> leaves)
    {
        for (int i = 0; i < leafNumber; i++)
        {
            float r = rectangleX;
            if (rectangleY > rectangleX)
                r = rectangleY;
            Vector3 p;
            do
            {
                p = Random.insideUnitSphere * r;
            }
            while (
                  p.x < rectangleX /*||
                  p.x > ellipsoidOffsetX.y * ellipsoidRadiusX ||
                  p.y < ellipsoidOffsetY.x * ellipsoidRadiusY ||
                  p.y > ellipsoidOffsetY.y * ellipsoidRadiusY ||
                  p.z < ellipsoidOffsetZ.x * ellipsoidRadiusZ ||
                  p.z > ellipsoidOffsetZ.y * ellipsoidRadiusZ*/ );
            leaves.Add(new Leaf2D(centerPosition + p));
        }
    }
}
